Proper connect_port
[juce-lv2.git] / juce / source / extras / the jucer / src / ui / jucer_MainWindow.cpp
blob8fd90cdeb8e035cba79d03f03b20150bc843626e
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../jucer_Headers.h"
27 #include "jucer_MainWindow.h"
28 #include "jucer_ComponentLayoutEditor.h"
29 #include "jucer_JucerDocumentHolder.h"
30 #include "jucer_PrefsPanel.h"
31 #include "jucer_TestComponent.h"
32 #include "../model/jucer_ObjectTypes.h"
33 #include "../properties/jucer_FontPropertyComponent.h"
36 static OldSchoolLookAndFeel* oldLook = 0;
37 static const int snapSizes[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32 };
39 //==============================================================================
40 class MultiDocHolder : public MultiDocumentPanel
42 public:
43 MultiDocHolder()
45 setBackgroundColour (Colour (0xffe6f0ff));
48 bool tryToCloseDocument (Component* component)
50 JucerDocumentHolder* const holder = dynamic_cast <JucerDocumentHolder*> (component);
52 return holder == 0
53 || holder->getDocument() == 0
54 || holder->getDocument()->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk;
58 //==============================================================================
59 MainWindow::MainWindow()
60 : DocumentWindow ("The Jucer",
61 Colours::azure,
62 DocumentWindow::allButtons)
64 if (oldLook == 0)
65 oldLook = new OldSchoolLookAndFeel();
67 setContentOwned (multiDocHolder = new MultiDocHolder(), false);
69 setApplicationCommandManagerToWatch (commandManager);
71 #if JUCE_MAC
72 setMacMainMenu (this);
73 #else
74 setMenuBar (this);
75 #endif
77 setResizable (true, false);
79 centreWithSize (700, 600);
81 // restore the last size and position from our settings file..
82 restoreWindowStateFromString (StoredSettings::getInstance()->getProps()
83 .getValue ("lastMainWindowPos"));
85 // Register all the app commands..
87 commandManager->registerAllCommandsForTarget (JUCEApplication::getInstance());
88 commandManager->registerAllCommandsForTarget (this);
90 // use a temporary one of these to harvest its commands..
91 JucerDocumentHolder tempDesignHolder (ObjectTypes::createNewDocument (0));
92 commandManager->registerAllCommandsForTarget (&tempDesignHolder);
95 commandManager->getKeyMappings()->resetToDefaultMappings();
97 XmlElement* const keys = StoredSettings::getInstance()->getProps().getXmlValue ("keyMappings");
99 if (keys != 0)
101 commandManager->getKeyMappings()->restoreFromXml (*keys);
102 delete keys;
105 addKeyListener (commandManager->getKeyMappings());
107 // don't want the window to take focus when the title-bar is clicked..
108 setWantsKeyboardFocus (false);
110 #ifndef JUCE_DEBUG
111 // scan for fonts before the app gets started rather than glitching later
112 FontPropertyComponent::preloadAllFonts();
113 #endif
116 MainWindow::~MainWindow()
118 #if JUCE_MAC
119 setMacMainMenu (0);
120 #else
121 setMenuBar (0);
122 #endif
124 removeKeyListener (commandManager->getKeyMappings());
126 // save the current size and position to our settings file..
127 StoredSettings::getInstance()->getProps()
128 .setValue ("lastMainWindowPos", getWindowStateAsString());
130 clearContentComponent();
132 deleteAndZero (oldLook);
135 void MainWindow::closeButtonPressed()
137 JUCEApplication::getInstance()->systemRequestedQuit();
140 JucerDocument* MainWindow::getActiveDocument() const throw()
142 JucerDocumentHolder* holder = dynamic_cast <JucerDocumentHolder*> (multiDocHolder->getActiveDocument());
144 if (holder == 0)
145 return 0;
147 return holder->getDocument();
150 bool MainWindow::closeAllDocuments()
152 return multiDocHolder->closeAllDocuments (true);
155 bool MainWindow::closeDocument (JucerDocumentHolder* designHolder)
157 return multiDocHolder->closeDocument (designHolder, true);
160 void MainWindow::openDocument (JucerDocument* const newDoc)
162 const File f (newDoc->getFile());
164 // check it's not already open..
165 if (f != File::nonexistent)
167 for (int i = multiDocHolder->getNumDocuments(); --i >= 0;)
169 JucerDocumentHolder* holder = dynamic_cast <JucerDocumentHolder*> (multiDocHolder->getDocument (i));
171 if (holder != 0 && holder->getDocument()->getFile() == f)
173 multiDocHolder->setActiveDocument (holder);
174 delete newDoc;
175 return;
180 multiDocHolder->addDocument (new JucerDocumentHolder (newDoc), Colour (0xffc4cdcd), true);
183 bool MainWindow::openFile (const File& file)
185 JucerDocument* newDoc = ObjectTypes::loadDocumentFromFile (file, true);
187 if (newDoc != 0)
188 openDocument (newDoc);
190 return newDoc != 0;
193 bool MainWindow::isInterestedInFileDrag (const StringArray& filenames)
195 for (int i = filenames.size(); --i >= 0;)
197 const File f (filenames[i]);
199 if (f.hasFileExtension (".cpp"))
200 return true;
203 return false;
206 void MainWindow::filesDropped (const StringArray& filenames, int mouseX, int mouseY)
208 for (int i = filenames.size(); --i >= 0;)
210 const File f (filenames[i]);
212 if (f.hasFileExtension (".cpp") && openFile (f))
213 break;
217 void MainWindow::activeWindowStatusChanged()
219 DocumentWindow::activeWindowStatusChanged();
221 if (isActiveWindow())
222 TestComponent::reloadAll();
225 //==============================================================================
226 const StringArray MainWindow::getMenuBarNames()
228 const char* const names[] = { "File", "Edit", "View", 0 };
230 return StringArray (names);
233 const PopupMenu MainWindow::getMenuForIndex (int topLevelMenuIndex,
234 const String& menuName)
236 PopupMenu menu;
238 if (topLevelMenuIndex == 0)
240 // "File" menu
242 for (int i = 0; i < ObjectTypes::numDocumentTypes; ++i)
243 menu.addCommandItem (commandManager, CommandIDs::newDocumentBase + i);
245 menu.addSeparator();
246 menu.addCommandItem (commandManager, CommandIDs::open);
248 PopupMenu recentFiles;
249 StoredSettings::getInstance()->recentFiles.createPopupMenuItems (recentFiles, 100, true, true);
250 menu.addSubMenu ("Open recent file", recentFiles);
252 menu.addSeparator();
253 menu.addCommandItem (commandManager, CommandIDs::close);
254 menu.addSeparator();
255 menu.addCommandItem (commandManager, CommandIDs::save);
256 menu.addCommandItem (commandManager, CommandIDs::saveAs);
257 menu.addSeparator();
259 menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit);
261 else if (topLevelMenuIndex == 1)
263 // "Edit" menu
265 menu.addCommandItem (commandManager, CommandIDs::undo);
266 menu.addCommandItem (commandManager, CommandIDs::redo);
267 menu.addSeparator();
269 menu.addCommandItem (commandManager, CommandIDs::editCompLayout);
270 menu.addCommandItem (commandManager, CommandIDs::editCompGraphics);
271 menu.addSeparator();
273 PopupMenu newComps;
274 int i;
275 for (i = 0; i < ObjectTypes::numComponentTypes; ++i)
276 newComps.addCommandItem (commandManager, CommandIDs::newComponentBase + i);
278 menu.addSubMenu ("Add new component", newComps);
280 PopupMenu newElements;
281 for (i = 0; i < ObjectTypes::numElementTypes; ++i)
282 newElements.addCommandItem (commandManager, CommandIDs::newElementBase + i);
284 menu.addSubMenu ("Add new graphic element", newElements);
286 menu.addSeparator();
287 menu.addCommandItem (commandManager, StandardApplicationCommandIDs::cut);
288 menu.addCommandItem (commandManager, StandardApplicationCommandIDs::copy);
289 menu.addCommandItem (commandManager, StandardApplicationCommandIDs::paste);
290 menu.addCommandItem (commandManager, StandardApplicationCommandIDs::del);
291 menu.addCommandItem (commandManager, StandardApplicationCommandIDs::selectAll);
292 menu.addCommandItem (commandManager, StandardApplicationCommandIDs::deselectAll);
293 menu.addSeparator();
294 menu.addCommandItem (commandManager, CommandIDs::toFront);
295 menu.addCommandItem (commandManager, CommandIDs::toBack);
296 menu.addSeparator();
297 menu.addCommandItem (commandManager, CommandIDs::group);
298 menu.addCommandItem (commandManager, CommandIDs::ungroup);
299 menu.addSeparator();
300 menu.addCommandItem (commandManager, CommandIDs::bringBackLostItems);
302 else if (topLevelMenuIndex == 2)
304 // "View" menu
306 menu.addCommandItem (commandManager, CommandIDs::test);
308 PopupMenu lookAndFeels;
309 lookAndFeels.addItem (201, "Default", true, (typeid (LookAndFeel) == typeid (LookAndFeel::getDefaultLookAndFeel())) != 0);
310 lookAndFeels.addItem (200, "Old School", true, (typeid (OldSchoolLookAndFeel) == typeid (LookAndFeel::getDefaultLookAndFeel())) != 0);
312 menu.addSeparator();
313 menu.addSubMenu ("Look and Feel", lookAndFeels);
315 menu.addSeparator();
316 menu.addCommandItem (commandManager, CommandIDs::showGrid);
317 menu.addCommandItem (commandManager, CommandIDs::enableSnapToGrid);
319 const int currentSnapSize = getActiveDocument() != 0 ? getActiveDocument()->getSnappingGridSize() : 0;
321 PopupMenu m;
322 for (int i = 0; i < numElementsInArray (snapSizes); ++i)
323 m.addItem (300 + i, String (snapSizes[i]) + " pixels", true, snapSizes[i] == currentSnapSize);
325 menu.addSubMenu ("Grid size", m, getActiveDocument() != 0);
327 menu.addSeparator();
328 menu.addCommandItem (commandManager, CommandIDs::zoomIn);
329 menu.addCommandItem (commandManager, CommandIDs::zoomOut);
330 menu.addCommandItem (commandManager, CommandIDs::zoomNormal);
332 menu.addSeparator();
333 PopupMenu overlays;
334 overlays.addCommandItem (commandManager, CommandIDs::compOverlay0);
335 overlays.addCommandItem (commandManager, CommandIDs::compOverlay33);
336 overlays.addCommandItem (commandManager, CommandIDs::compOverlay66);
337 overlays.addCommandItem (commandManager, CommandIDs::compOverlay100);
338 menu.addSubMenu ("Component Overlay", overlays,
339 getActiveDocument() != 0 && getActiveDocument()->getComponentLayout() != 0);
341 menu.addSeparator();
342 menu.addCommandItem (commandManager, CommandIDs::useTabbedWindows);
343 menu.addSeparator();
344 menu.addCommandItem (commandManager, CommandIDs::showPrefs);
347 return menu;
350 void MainWindow::menuItemSelected (int menuItemID,
351 int topLevelMenuIndex)
353 if (menuItemID >= 100 && menuItemID < 200)
355 // open a file from the "recent files" menu
356 JucerDocument* const newDoc
357 = ObjectTypes::loadDocumentFromFile (StoredSettings::getInstance()->recentFiles.getFile (menuItemID - 100),
358 true);
360 if (newDoc != 0)
361 openDocument (newDoc);
363 else if (menuItemID == 200)
365 LookAndFeel::setDefaultLookAndFeel (oldLook);
367 else if (menuItemID == 201)
369 LookAndFeel::setDefaultLookAndFeel (nullptr);
371 else if (menuItemID >= 300 && menuItemID < 400)
373 if (getActiveDocument() != 0)
375 getActiveDocument()->setSnappingGrid (snapSizes [menuItemID - 300],
376 getActiveDocument()->isSnapActive (false),
377 getActiveDocument()->isSnapShown());
382 //==============================================================================
383 ApplicationCommandTarget* MainWindow::getNextCommandTarget()
385 return 0;
388 void MainWindow::getAllCommands (Array <CommandID>& commands)
390 for (int i = 0; i < ObjectTypes::numDocumentTypes; ++i)
391 commands.add (CommandIDs::newDocumentBase + i);
393 const CommandID ids[] = { CommandIDs::open,
394 CommandIDs::showPrefs,
395 CommandIDs::useTabbedWindows };
397 commands.addArray (ids, numElementsInArray (ids));
400 void MainWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
402 if (commandID >= CommandIDs::newDocumentBase
403 && commandID < CommandIDs::newDocumentBase + ObjectTypes::numDocumentTypes)
405 const int index = commandID - CommandIDs::newDocumentBase;
407 result.setInfo ("New " + String (ObjectTypes::documentTypeNames [index]),
408 "Creates a new " + String (ObjectTypes::documentTypeNames[index]),
409 CommandCategories::general, 0);
411 return;
414 const int cmd = ModifierKeys::commandModifier;
416 switch (commandID)
418 case CommandIDs::open:
419 result.setInfo ("Open...",
420 "Opens a Jucer .cpp component file for editing.",
421 CommandCategories::general, 0);
422 result.defaultKeypresses.add (KeyPress ('o', cmd, 0));
423 break;
425 case CommandIDs::showPrefs:
426 result.setInfo ("Preferences...",
427 "Shows the preferences panel.",
428 CommandCategories::general, 0);
429 result.defaultKeypresses.add (KeyPress (',', cmd, 0));
430 break;
432 case CommandIDs::useTabbedWindows:
433 result.setInfo ("Use tabs to show windows",
434 "Flips between a tabbed component and separate windows",
435 CommandCategories::general, 0);
436 result.setTicked (multiDocHolder->getLayoutMode() == MultiDocumentPanel::MaximisedWindowsWithTabs);
437 break;
439 default:
440 break;
444 bool MainWindow::isCommandActive (const CommandID commandID)
446 return true;
449 bool MainWindow::perform (const InvocationInfo& info)
451 if (info.commandID >= CommandIDs::newDocumentBase
452 && info.commandID < CommandIDs::newDocumentBase + ObjectTypes::numDocumentTypes)
454 const int index = info.commandID - CommandIDs::newDocumentBase;
455 openDocument (ObjectTypes::createNewDocument (index));
457 return true;
460 switch (info.commandID)
462 case CommandIDs::open:
463 openFile (File::nonexistent);
464 break;
466 case CommandIDs::showPrefs:
467 PrefsPanel::show();
468 break;
470 case CommandIDs::useTabbedWindows:
471 if (multiDocHolder->getLayoutMode() == MultiDocumentPanel::MaximisedWindowsWithTabs)
472 multiDocHolder->setLayoutMode (MultiDocumentPanel::FloatingWindows);
473 else
474 multiDocHolder->setLayoutMode (MultiDocumentPanel::MaximisedWindowsWithTabs);
476 break;
478 default:
479 return false;
482 return true;